package com.mall.user.services;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mall.user.ILoginService;
import com.mall.user.constants.SysRetCodeConstants;
import com.mall.user.converter.UserConverterMapper;
import com.mall.user.dal.entitys.Member;
import com.mall.user.dal.persistence.MemberMapper;
import com.mall.user.dto.*;
import com.mall.user.utils.ExceptionProcessorUtils;
import com.mall.user.utils.JwtTokenUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description:
 * @Author: JK 、Yi Xinhao
 * @Date: create in 2021/7/20 20:45
 */
@Service
@Slf4j
public class LoginServiceImpl implements ILoginService {
    @Autowired
    MemberMapper memberMapper;

    @Autowired
    UserConverterMapper userConverterMapper;

    @Override
    public UserLoginResponse userLogin(UserLoginRequest request) {
        UserLoginResponse response = new UserLoginResponse();

        try {
            // 校验请求参数是否合法
            request.requestCheck();

            //注意这里要把request里面的密码取出来后，用md5工具类加密，再带入进行校验
            String password = request.getPassword();
            System.out.println("登录未加密的密码：" + password);

            password = DigestUtils.md5DigestAsHex(password.getBytes());

            System.out.println("登录加密后的密码：" + password);

            Example example = new Example(Member.class);
            example.createCriteria()
                    .andEqualTo("username", request.getUserName())
                    .andEqualTo("password", password);

            List<Member> members = memberMapper.selectByExample(example);

            //找到了一个members
            if (members.size() == 1) {
                Member member = members.get(0);
                response = userConverterMapper.converter(member);
                response.setCode(SysRetCodeConstants.SUCCESS.getCode());
                response.setMsg(SysRetCodeConstants.SUCCESS.getMessage());

                //创建一个userInfoMap，把userId放进去，然后用Jason序列化map为一个字符串userInfoJson
                Map<String, String> userInfoMap = new HashMap<String, String>();
                userInfoMap.put("uid", String.valueOf(member.getId()));
                String userInfoJson = JSON.toJSONString(userInfoMap);
                //借助JwtTokenUtils工具类，把之前生成的字符串userInfoJson加密为token
                JwtTokenUtils jwtTokenUtils = JwtTokenUtils.builder().msg(userInfoJson).build();
                String token = jwtTokenUtils.creatJwtToken();
                //把token set进response中
                response.setToken(token);
            } else if (members.size() == 0) {
                response.setCode(SysRetCodeConstants.USERORPASSWORD_ERRROR.getCode());
                response.setMsg(SysRetCodeConstants.USERORPASSWORD_ERRROR.getMessage());
            } else {
                response.setCode(SysRetCodeConstants.DB_EXCEPTION.getCode());
                response.setMsg(SysRetCodeConstants.DB_EXCEPTION.getMessage());
            }
        } catch (Exception e) {
            log.info("UserServiceImpl#userLogin " + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
            //e.printStackTrace();
        }
        return response;
    }

    @Override
    public UserLoginStatusResponse userLoginVerify(UserLoginStatusRequest request) {
        UserLoginStatusResponse response = new UserLoginStatusResponse();

        try {
            // 校验请求参数是否合法
            request.requestCheck();
            //Jwt解密拿到token的解析结果
            JwtTokenUtils jwtTokenUtils = JwtTokenUtils.builder().token(request.getToken()).build();
            String userInfo = jwtTokenUtils.freeJwt();
            //把解析出来的jason字符串反序列化为一个map对象，从中取uid对应的值
            JSONObject object = JSON.parseObject(userInfo);
            Long uid = Long.parseLong(object.get("uid").toString());
            //用用户id找到对应用户对象
            Member member = memberMapper.selectByPrimaryKey(uid);

            if (member != null) {
                UserLoginStatusResponseDto userLoginStatusResponseDto = userConverterMapper.member2Res(member);
                response.setUserLoginStatusResponseDto(userLoginStatusResponseDto);
                response.setCode(SysRetCodeConstants.SUCCESS.getCode());
                response.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
            } else {
                // 未查询到用户，说明token校验失败
                response.setCode(SysRetCodeConstants.TOKEN_VALID_FAILED.getCode());
                response.setCode(SysRetCodeConstants.TOKEN_VALID_FAILED.getMessage());
            }
        } catch (Exception e) {
            log.info("UserServiceImpl#userLoginStatus " + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
            //e.printStackTrace();
        }

        return response;
    }

    @Override
    public CheckAuthResponse validToken(CheckAuthRequest request) {
        CheckAuthResponse response = new CheckAuthResponse();

        try {
            // 校验请求参数是否合法
            request.requestCheck();
            //首先Jwt解密
            JwtTokenUtils jwtTokenUtils = JwtTokenUtils.builder().token(request.getToken()).build();
            String userInfo = jwtTokenUtils.freeJwt();
            //把jason字符串反序列化为对象，这个对象其实是一个map
            JSONObject object = JSON.parseObject(userInfo);
            //从map里面取出key为uid对应的值
            Long uid = Long.parseLong(object.get("uid").toString());
            Member member = memberMapper.selectByPrimaryKey(uid);

            if (member != null) {
                // 查询到用户，说明token校验成功
                response.setCode(SysRetCodeConstants.SUCCESS.getCode());
                response.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
                //把从解密后的map中拿到的用户id值整理为String形式然后set进response中
                response.setUserinfo(uid.toString());
            } else {
                // 未查询到用户，说明token校验失败
                response.setCode(SysRetCodeConstants.TOKEN_VALID_FAILED.getCode());
                response.setCode(SysRetCodeConstants.TOKEN_VALID_FAILED.getMessage());
            }
        } catch (Exception e) {
            log.info("UserServiceImpl#validToken " + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
            //e.printStackTrace();
        }
        return response;
    }

}
